In [375]:
!pip install pandas matplotlib numpy statsmodels seaborn scipy -q
[notice] A new release of pip is available: 24.3.1 -> 25.1.1
[notice] To update, run: pip install --upgrade pip
In [376]:
# Import all datasets for sit to stand
import pandas as pd
from data_collector import get_sit_to_stand_paths, get_sit_to_stand_challenge_paths, get_water_task_paths, get_water_task_challenge_paths, get_step_count_paths, get_step_count_challenge_paths
import numpy as np

task = 'step_count'
if task == 'sit2stand':
    paths_standard = get_sit_to_stand_paths()
    paths_challenge = get_sit_to_stand_challenge_paths()
elif task == 'water':
    paths_standard = get_water_task_paths()
    paths_challenge = get_water_task_challenge_paths()
elif task == 'step_count':
    paths_standard = get_step_count_paths()
    paths_challenge = get_step_count_challenge_paths()


dfs_stand = [pd.read_csv(path) for path in paths_standard]
dfs_stand_challenge = [pd.read_csv(path) for path in paths_challenge]

# For each dataframe, add a new column 'time_s' which is the time in seconds from the first timestamp
for df in dfs_stand:
    df['time_s'] = (df['timestamp_ms'] - df['timestamp_ms'].min()) / 1000


for df in dfs_stand_challenge:
    df['time_s'] = (df['timestamp_ms'] - df['timestamp_ms'].min()) / 1000

if task=='step_count':
    # rename column from acceleration_m/s²_x to 'freeAcceleration_m/s²_x' for x y and z
    dfs_stand = [df.rename(columns={'acceleration_m/s²_x': 'freeAcceleration_m/s²_x', 'acceleration_m/s²_y': 'freeAcceleration_m/s²_y', 'acceleration_m/s²_z': 'freeAcceleration_m/s²_z'}) for df in dfs_stand]
    dfs_stand_challenge = [df.rename(columns={'acceleration_m/s²_x': 'freeAcceleration_m/s²_x', 'acceleration_m/s²_y': 'freeAcceleration_m/s²_y', 'acceleration_m/s²_z': 'freeAcceleration_m/s²_z'}) for df in dfs_stand_challenge]

# Calculate magnitude of acceleration 
for df in dfs_stand:
    df['acceleration_magnitude'] = np.sqrt(
        df['freeAcceleration_m/s²_x']**2 + 
        df['freeAcceleration_m/s²_y']**2 + 
        df['freeAcceleration_m/s²_z']**2
    )

for df in dfs_stand_challenge:
    df['acceleration_magnitude'] = np.sqrt(
        df['freeAcceleration_m/s²_x']**2 + 
        df['freeAcceleration_m/s²_y']**2 + 
        df['freeAcceleration_m/s²_z']**2
    )


df_standard = dfs_stand[0]
df_challenge = dfs_stand_challenge[0]

print(f"Using data from {paths_standard[0]} and {paths_challenge[0]}")
Data directory to look in: /Users/ashish/Desktop/DS4W/sensorhub-analysis/data
Sub directories for each Device ID found: ['f3eba7e5-dbda-4f4c-9fa8-8e8308b334f6', '5f680dfb-2510-4790-8f10-cb8724e7004c', '3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8']
Data directory to look in: /Users/ashish/Desktop/DS4W/sensorhub-analysis/data
Sub directories for each Device ID found: ['f3eba7e5-dbda-4f4c-9fa8-8e8308b334f6', '5f680dfb-2510-4790-8f10-cb8724e7004c', '3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8']
Using data from /Users/ashish/Desktop/DS4W/sensorhub-analysis/data/3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8/csv/Recordings_Signal_Data/2025-05-12T07_02_15Z-step_count/Internal Accelerometer_accelerometer.csv and /Users/ashish/Desktop/DS4W/sensorhub-analysis/data/3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8/csv/Recordings_Signal_Data/2025-05-12T07_03_14Z-step_count_challenge/Internal Accelerometer_accelerometer.csv
Using data from /Users/ashish/Desktop/DS4W/sensorhub-analysis/data/3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8/csv/Recordings_Signal_Data/2025-05-12T07_02_15Z-step_count/Internal Accelerometer_accelerometer.csv and /Users/ashish/Desktop/DS4W/sensorhub-analysis/data/3c2d2423-8ac8-4a8c-95e2-aba5cc14abf8/csv/Recordings_Signal_Data/2025-05-12T07_03_14Z-step_count_challenge/Internal Accelerometer_accelerometer.csv

Experimental Design¶

  • Within-subject study: Each participant (N = 5) performs:

    • Sit-to-stand under normal conditions
    • Sit-to-stand while doing a cognitive task (serial subtraction)
  • Data collected:

    • Timestamped acceleration on 3 axes (x, y, z) for ~30 seconds per trial

Step 1: Compute Acceleration Magnitude¶

We reduce the 3D accelerometer signal into a single scalar by computing the magnitude of free acceleration at each time point:

$$ \text{acc_mag}(t) = \sqrt{x_t^2 + y_t^2 + z_t^2} $$

This gives us a time-series that reflects total body movement intensity.


📉 Step 2: Feature Extraction — Mean Acceleration¶

We summarize the signal for each trial (one per participant per condition) by computing the mean acceleration magnitude:

$$ \bar{a} = \frac{1}{T} \sum_{t=1}^{T} \text{acc_mag}(t) $$

Where:

  • T is the number of time points in the trial
  • a' represents the average movement intensity

🔍 Step 3: Statistical Testing — Paired t-test¶

To assess whether the cognitive condition affects mean acceleration, we compare the values within participants using a paired t-test.

Let the difference for each participant be:

$$ D_i = a_{\text{normal},i} - a_{\text{cognitive},i} $$

We test the null hypothesis:

$$ H_0: \mu_D = 0 \quad \text{(no difference)} $$

With the t-statistic:

$$ t = \frac{\bar{D}}{s_D / \sqrt{n}} $$

Where:

  • D' is the mean of the differences
  • s_D is the standard deviation of the differences
  • n is the number of participants

If the resulting p-value < 0.05, we reject ( H_0 ), concluding that cognitive load significantly alters movement.


In [377]:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime

# Convert timestamps to datetime for better x-axis labels
# Create a relative time in seconds from the first timestamp
def visualize_data(df):
    # Plot the acceleration data
    plt.figure(figsize=(12, 8))

    # Plot each axis
    plt.subplot(3, 1, 1)
    plt.plot(df['time_s'], df['freeAcceleration_m/s²_x'], 'r-', label='X-axis')
    plt.ylabel('Acceleration (m/s²)')
    plt.title('Free Acceleration X-axis')
    plt.grid(True)
    plt.legend()

    plt.subplot(3, 1, 2)
    plt.plot(df['time_s'], df['freeAcceleration_m/s²_y'], 'g-', label='Y-axis')
    plt.ylabel('Acceleration (m/s²)')
    plt.title('Free Acceleration Y-axis')
    plt.grid(True)
    plt.legend()

    plt.subplot(3, 1, 3)
    plt.plot(df['time_s'], df['freeAcceleration_m/s²_z'], 'b-', label='Z-axis')
    plt.xlabel('Time (seconds)')
    plt.ylabel('Acceleration (m/s²)')
    plt.title('Free Acceleration Z-axis')
    plt.grid(True)
    plt.legend()

    plt.tight_layout()
    plt.show()

    # Combined view of all three axes
    plt.figure(figsize=(12, 6))
    plt.plot(df['time_s'], df['freeAcceleration_m/s²_x'], 'r-', label='X-axis')
    plt.plot(df['time_s'], df['freeAcceleration_m/s²_y'], 'g-', label='Y-axis')
    plt.plot(df['time_s'], df['freeAcceleration_m/s²_z'], 'b-', label='Z-axis')
    plt.xlabel('Time (seconds)')
    plt.ylabel('Acceleration (m/s²)')
    plt.title('Free Acceleration - All Axes')
    plt.grid(True)
    plt.legend()
    plt.tight_layout()
    plt.show()

    # Plot the magnitude
    plt.figure(figsize=(12, 5))
    plt.plot(df['time_s'], df['acceleration_magnitude'], 'k-')
    plt.xlabel('Time (seconds)')
    plt.ylabel('Acceleration Magnitude (m/s²)')
    plt.title('Magnitude of Acceleration')
    plt.grid(True)
    plt.tight_layout()
    plt.show()
In [378]:
# Visualize normal data
visualize_data(df_standard)
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
In [379]:
# Visualize challenge data
visualize_data(df_challenge)
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
In [380]:
# Compare both data x-axis acceleration
def compare_acceleration_x(df, df_challenge):
    plt.figure(figsize=(12, 6))
    plt.plot(df['time_s'], df['freeAcceleration_m/s²_x'], 'r-', label='Normal')
    plt.plot(df_challenge['time_s'], df_challenge['freeAcceleration_m/s²_x'], 'b-', label='Challenge')
    plt.xlabel('Time (seconds)')
    plt.ylabel('Acceleration (m/s²)')
    plt.title('X-axis Acceleration Comparison')
    plt.legend()
    plt.show()

# Compare both data x-axis acceleration
compare_acceleration_x(df_standard, df_challenge)
No description has been provided for this image
In [381]:
# Compare both data y-axis acceleration
def compare_acceleration_y(df, df_challenge):
    plt.figure(figsize=(12, 6))
    plt.plot(df['time_s'], df['freeAcceleration_m/s²_y'], 'r-', label='Normal')
    plt.plot(df_challenge['time_s'], df_challenge['freeAcceleration_m/s²_y'], 'b-', label='Challenge')
    plt.xlabel('Time (seconds)')
    plt.ylabel('Acceleration (m/s²)')
    plt.title('Y-axis Acceleration Comparison')
    plt.legend()
    plt.show()

# Compare both data y-axis acceleration
compare_acceleration_y(df_standard, df_challenge)
No description has been provided for this image
In [382]:
# Compare both data z-axis acceleration
def compare_acceleration_z(df, df_challenge):
    plt.figure(figsize=(12, 6))
    plt.plot(df['time_s'], df['freeAcceleration_m/s²_z'], 'r-', label='Normal')
    plt.plot(df_challenge['time_s'], df_challenge['freeAcceleration_m/s²_z'], 'b-', label='Challenge')
    plt.xlabel('Time (seconds)')
    plt.ylabel('Acceleration (m/s²)')
    plt.title('Y-axis Acceleration Comparison')
    plt.legend()
    plt.show()

# Compare both data z-axis acceleration
compare_acceleration_z(df_standard, df_challenge)
No description has been provided for this image
In [383]:
# Compare both data magnitude of acceleration
def compare_acceleration_magnitude(df, df_challenge):
    plt.figure(figsize=(12, 6))
    plt.plot(df['time_s'], df['acceleration_magnitude'], 'r-', label='Normal')
    plt.plot(df_challenge['time_s'], df_challenge['acceleration_magnitude'], 'b-', label='Challenge')
    plt.xlabel('Time (seconds)')
    plt.ylabel('Acceleration Magnitude (m/s²)')
    plt.title('Magnitude of Acceleration Comparison')
    plt.legend()
    plt.show()

# Compare both data magnitude of acceleration
compare_acceleration_magnitude(df_standard, df_challenge)
No description has been provided for this image
In [384]:
# Compare x-acceleration across all participants
def compare_acceleration_x_all(dfs, axis='x'):
    plt.figure(figsize=(20, 6))
    for i, df in enumerate(dfs):
        plt.plot(df['time_s'], df[f'freeAcceleration_m/s²_{axis}'], label=f'Participant {i+1}')
    plt.xlabel('Time (seconds)')
    plt.ylabel('Acceleration (m/s²)')
    plt.title(f'{axis}-axis Acceleration Comparison')

    plt.legend()
    plt.show()


# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand)

# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand, 'y')

# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand, 'z')
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
In [385]:
# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand_challenge, 'x')

# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand_challenge, 'y')

# Compare x-acceleration across all participants
compare_acceleration_x_all(dfs_stand_challenge, 'z')
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
In [ ]:

In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [386]:
len(dfs_stand), dfs_stand
Out[386]:
(5,
 [       timestamp_ms  freeAcceleration_m/s²_x  freeAcceleration_m/s²_y  \
  0     1747033335167                -0.895215                 2.819942   
  1     1747033335199                -0.580858                 2.885744   
  2     1747033335215                -0.576072                 2.963212   
  3     1747033335263                 0.057129                 3.147758   
  4     1747033335294                 0.043071                 3.035296   
  ...             ...                      ...                      ...   
  1093  1747033365375                -0.058325                 0.618246   
  1094  1747033365407                -1.164407                 0.292523   
  1095  1747033365423                -1.383351                 0.353839   
  1096  1747033365471                -2.008774                 0.601795   
  1097  1747033365503                -1.447957                 1.105185   
  
        freeAcceleration_m/s²_z  time_s  acceleration_magnitude  
  0                    8.994321   0.000                9.468437  
  1                    8.695518   0.032                9.180248  
  2                    8.683254   0.048                9.193007  
  3                    9.101998   0.096                9.631096  
  4                    9.285348   0.127                9.768959  
  ...                       ...     ...                     ...  
  1093                10.159028  30.208               10.177990  
  1094                10.748261  30.240               10.815106  
  1095                10.637293  30.256               10.732701  
  1096                 9.495916  30.304                9.724698  
  1097                 9.175877  30.336                9.354931  
  
  [1098 rows x 6 columns],
         timestamp_ms  freeAcceleration_m/s²_x  freeAcceleration_m/s²_y  \
  0     1746707114626                -1.446162                 2.251646   
  1     1746707114658                -1.409074                 2.175973   
  2     1746707114707                -1.507179                 2.025823   
  3     1746707114722                -1.503590                 2.021038   
  4     1746707114754                -1.628914                 2.047957   
  ...             ...                      ...                      ...   
  1178  1746707146530                -1.336391                 0.938884   
  1179  1746707146562                -1.496411                 1.640878   
  1180  1746707146578                -0.788435                 1.118645   
  1181  1746707146610                -0.515653                 1.587638   
  1182  1746707146642                 0.235095                 1.702493   
  
        freeAcceleration_m/s²_z  time_s  acceleration_magnitude  
  0                    9.483952   0.000                9.854271  
  1                    9.491131   0.032                9.838796  
  2                    9.623633   0.081                9.949365  
  3                    9.473783   0.096                9.802956  
  4                    9.515657   0.128                9.868902  
  ...                       ...     ...                     ...  
  1178                 9.347860  31.904                9.489464  
  1179                10.793724  31.936               11.019810  
  1180                 9.958928  31.952               10.052524  
  1181                 9.188140  31.984                9.338544  
  1182                 8.387142  32.016                8.561420  
  
  [1183 rows x 6 columns],
         timestamp_ms  freeAcceleration_m/s²_x  freeAcceleration_m/s²_y  \
  0     1746708696802                 1.230210                 3.256632   
  1     1746708696818                 1.144068                 3.308975   
  2     1746708696866                 1.009472                 3.437589   
  3     1746708696883                 0.967299                 3.452245   
  4     1746708696914                 0.967897                 3.504588   
  ...             ...                      ...                      ...   
  1146  1746708727458                -1.123729                 1.488336   
  1147  1746708727490                -0.541077                 1.222732   
  1148  1746708727506                -1.536192                 2.203491   
  1149  1746708727539                -0.029910                 2.172085   
  1150  1746708727555                 0.255434                 2.452643   
  
        freeAcceleration_m/s²_z  time_s  acceleration_magnitude  
  0                    8.897113   0.000                9.553936  
  1                    8.875278   0.016                9.540900  
  2                    8.701201   0.064                9.409938  
  3                    8.756235   0.081                9.461782  
  4                    8.665906   0.112                9.397707  
  ...                       ...     ...                     ...  
  1146                 6.812067  30.656                7.062731  
  1147                10.696217  30.688               10.779466  
  1148                10.473085  30.704               10.812066  
  1149                 7.900801  30.737                8.193992  
  1150                 6.884749  30.753                7.313035  
  
  [1151 rows x 6 columns],
         timestamp_ms  freeAcceleration_m/s²_x  freeAcceleration_m/s²_y  \
  0     1746707353970                 0.213859                 3.412165   
  1     1746707353986                 0.374477                 3.434897   
  2     1746707354002                 0.470190                 3.475575   
  3     1746707354034                 0.306580                 3.707679   
  4     1746707354051                 0.259920                 3.750750   
  ...             ...                      ...                      ...   
  1100  1746707384371                -0.897608                 1.856830   
  1101  1746707384402                -0.589233                 1.917847   
  1102  1746707384434                -0.453739                 2.145165   
  1103  1746707384450                -0.362513                 2.029712   
  1104  1746707384483                -0.651147                 2.011467   
  
        freeAcceleration_m/s²_z  time_s  acceleration_magnitude  
  0                    9.294920   0.000                9.903744  
  1                    9.021839   0.016                9.660866  
  2                    8.756834   0.032                9.433072  
  3                    8.500801   0.064                9.279251  
  4                    8.576474   0.081                9.364379  
  ...                       ...     ...                     ...  
  1100                10.803893  30.401               10.998983  
  1101                 8.788837  30.432                9.014931  
  1102                 8.138288  30.464                8.428485  
  1103                 8.234600  30.480                8.488803  
  1104                 9.437891  30.513                9.671803  
  
  [1105 rows x 6 columns],
         timestamp_ms  freeAcceleration_m/s²_x  freeAcceleration_m/s²_y  \
  0     1747033460847                -0.658026                 1.848755   
  1     1747033460879                -0.723530                 1.911865   
  2     1747033460927                -0.523729                 2.000101   
  3     1747033460959                -0.455534                 2.054537   
  4     1747033460975                -0.505185                 2.107179   
  ...             ...                      ...                      ...   
  1083  1747033491055                -0.598804                 2.568097   
  1084  1747033491135                -0.500100                 2.051546   
  1085  1747033491167                -0.401097                 2.318944   
  1086  1747033491183                -0.325125                 2.359921   
  1087  1747033491215                 0.594916                 2.088037   
  
        freeAcceleration_m/s²_z  time_s  acceleration_magnitude  
  0                    9.765707   0.000                9.960920  
  1                    9.685548   0.032                9.898917  
  2                    9.436396   0.080                9.660241  
  3                    9.219545   0.112                9.456672  
  4                    9.149555   0.128                9.402647  
  ...                       ...     ...                     ...  
  1083                 9.646963  30.208               10.000879  
  1084                10.144073  30.288               10.361523  
  1085                 9.937094  30.320               10.211964  
  1086                 9.508180  30.336                9.802062  
  1087                10.854442  30.368               11.069450  
  
  [1088 rows x 6 columns]])
In [387]:
# Compare number of rows in each participant's data by plotting
import matplotlib.pyplot as plt

# Create a list to store the number of rows for each participant
num_rows_list_standard = [len(df) for df in dfs_stand]
num_rows_list_challenge = [len(df) for df in dfs_stand_challenge]

# PLot bar chart of number of rows for each participant with participant number on x-axis
plt.figure(figsize=(14, 6))
plt.bar(range(len(num_rows_list_standard)), num_rows_list_standard, label='Standard')
# Label each bar with the number of samples in the participant's data 
for i, num_rows in enumerate(num_rows_list_standard):
    plt.text(i, num_rows, str(num_rows), ha='center', va='bottom')
plt.xlabel('Participant')
plt.ylabel('Number of Rows')
plt.title('Number of Rows in Each Participant in Standard Task')
plt.legend()
Out[387]:
<matplotlib.legend.Legend at 0x11403e650>
No description has been provided for this image
In [388]:
plt.figure(figsize=(12, 6))
plt.bar(range(len(num_rows_list_challenge)), num_rows_list_challenge, label='Challenge')
for i, num_rows in enumerate(num_rows_list_challenge):
    plt.text(i, num_rows, str(num_rows), ha='center', va='bottom')
plt.xlabel('Participant')
plt.ylabel('Number of Rows')
plt.title('Number of Rows in Each Participant in Challenge Task')
plt.legend()
Out[388]:
<matplotlib.legend.Legend at 0x133c46140>
No description has been provided for this image
In [389]:
# Plot a double, non overlapping bar chart of number of rows for standard and challenge tasks
count_df = pd.DataFrame({
    'Standard': num_rows_list_standard,
    'Challenge': num_rows_list_challenge
})
count_df.plot(kind='bar', figsize=(12, 6))
plt.xlabel('Participant')
plt.ylabel('Number of Rows')
plt.title('Number of Rows in Each Participant in Standard and Challenge Tasks')
plt.legend()
Out[389]:
<matplotlib.legend.Legend at 0x11237b370>
No description has been provided for this image
In [390]:
# Calculate mean acceleration for each axis per participant 
mean_acceleration_standard_x = [df['freeAcceleration_m/s²_x'].mean() for df in dfs_stand]
mean_acceleration_challenge_x = [df['freeAcceleration_m/s²_x'].mean() for df in dfs_stand_challenge]
mean_acceleration_standard_y = [df['freeAcceleration_m/s²_y'].mean() for df in dfs_stand]
mean_acceleration_challenge_y = [df['freeAcceleration_m/s²_y'].mean() for df in dfs_stand_challenge]
mean_acceleration_standard_z = [df['freeAcceleration_m/s²_z'].mean() for df in dfs_stand]
mean_acceleration_challenge_z = [df['freeAcceleration_m/s²_z'].mean() for df in dfs_stand_challenge]

# Plot and compare mean acceleration for each axis per participant
def plot_mean_acceleration(mean_acceleration_standard, mean_acceleration_challenge, axis='x'):
    plt.figure(figsize=(12, 6))
    plt.bar(range(len(mean_acceleration_standard)), mean_acceleration_standard, label='Standard')
    plt.bar(range(len(mean_acceleration_challenge)), mean_acceleration_challenge, label='Challenge')
    # Label each bar with the mean acceleration, rounded to 2 decimal places
    for i, mean_acceleration in enumerate(mean_acceleration_standard):
        # write text in blue color
        plt.text(i, mean_acceleration, str(round(mean_acceleration, 4)), ha='center', va='bottom', color='blue')
    for i, mean_acceleration in enumerate(mean_acceleration_challenge_x):
        plt.text(i, mean_acceleration, str(round(mean_acceleration, 4)), ha='center', va='bottom', color='black')
    plt.xlabel('Participant')
    plt.ylabel(f"Mean Acceleration in {axis}-axis (m/s²)")
    plt.title('Mean Acceleration in Standard and Challenge Tasks')
    plt.legend()
In [391]:
# Mean acceleration for x axis
plot_mean_acceleration(mean_acceleration_standard_x, mean_acceleration_challenge_x, 'x')
No description has been provided for this image
In [392]:
# Mean acceleration for y axis
plot_mean_acceleration(mean_acceleration_standard_y, mean_acceleration_challenge_y, 'y')
No description has been provided for this image
In [393]:
# Mean acceleration for z axis
plot_mean_acceleration(mean_acceleration_standard_z, mean_acceleration_challenge_z, 'z')
No description has been provided for this image
In [394]:
# Plot sample means using qq plots
import statsmodels.api as sm

# Create a list to store the sample means for each participant
sample_means_standard_x = np.array([df['freeAcceleration_m/s²_x'].mean() for df in dfs_stand])
sample_means_challenge_x = np.array([df['freeAcceleration_m/s²_x'].mean() for df in dfs_stand_challenge])
sample_means_standard_y = np.array([df['freeAcceleration_m/s²_y'].mean() for df in dfs_stand])
sample_means_challenge_y = np.array([df['freeAcceleration_m/s²_y'].mean() for df in dfs_stand_challenge])
sample_means_standard_z = np.array([df['freeAcceleration_m/s²_z'].mean() for df in dfs_stand])
sample_means_challenge_z = np.array([df['freeAcceleration_m/s²_z'].mean() for df in dfs_stand_challenge])

fig, axs = plt.subplots(2, 3, figsize=(20, 12), sharex=True)


# Plot qq plot of sample means and add labels
sm.qqplot(sample_means_standard_x, line='45', fit=True, ax=axs[0, 0])
axs[0, 0].set_xlabel('Theoretical Quantiles')
axs[0, 0].set_ylabel('Sample Quantiles')
axs[0, 0].set_title('QQ Plot of Sample Means for Standard Task along x-axis')
axs[0, 0].legend()

# Plot qq plot of sample means
sm.qqplot(sample_means_challenge_x, line='45', fit=True, ax=axs[1, 0])
axs[1, 0].set_xlabel('Theoretical Quantiles')
axs[1, 0].set_ylabel('Sample Quantiles')
axs[1, 0].set_title('QQ Plot of Sample Means for Challenge Task along x-axis')
axs[1, 0].legend()

# Plot qq plot of sample means
sm.qqplot(sample_means_standard_y, line='45', fit=True, ax=axs[0, 1])
axs[0, 1].set_xlabel('Theoretical Quantiles')
axs[0, 1].set_ylabel('Sample Quantiles')
axs[0, 1].set_title('QQ Plot of Sample Means for Standard Task along y-axis')
axs[0, 1].legend()

# Plot qq plot of sample means
sm.qqplot(sample_means_challenge_y, line='45', fit=True, ax=axs[1, 1])
axs[1, 1].set_xlabel('Theoretical Quantiles')
axs[1, 1].set_ylabel('Sample Quantiles')
axs[1, 1].set_title('QQ Plot of Sample Means for Challenge Task along y-axis')
axs[1, 1].legend()

# Plot qq plot of sample means
sm.qqplot(sample_means_standard_z, line='45', fit=True, ax=axs[0, 2])
axs[0, 2].set_xlabel('Theoretical Quantiles')
axs[0, 2].set_ylabel('Sample Quantiles')
axs[0, 2].set_title('QQ Plot of Sample Means for Standard Task along z-axis')
axs[0, 2].legend()

# Plot qq plot of sample means
sm.qqplot(sample_means_challenge_z, line='45', fit=True, ax=axs[1, 2])
axs[1, 2].set_xlabel('Theoretical Quantiles')
axs[1, 2].set_ylabel('Sample Quantiles')
axs[1, 2].set_title('QQ Plot of Sample Means for Challenge Task along z-axis')
axs[1, 2].legend()
/var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:20: UserWarning: No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
  axs[0, 0].legend()
/var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:27: UserWarning: No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
  axs[1, 0].legend()
/var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:34: UserWarning: No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
  axs[0, 1].legend()
/var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:41: UserWarning: No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
  axs[1, 1].legend()
/var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:48: UserWarning: No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
  axs[0, 2].legend()
/var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/3602491626.py:55: UserWarning: No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
  axs[1, 2].legend()
Out[394]:
<matplotlib.legend.Legend at 0x134fa2a70>
No description has been provided for this image
In [395]:
# Calculate magnitude of acceleration for each participant
mean_acceleration_standard_magnitude = np.array([df['acceleration_magnitude'].mean() for df in dfs_stand])
mean_acceleration_challenge_magnitude = np.array([df['acceleration_magnitude'].mean() for df in dfs_stand_challenge])

mean_acceleration_standard_magnitude, mean_acceleration_challenge_magnitude
Out[395]:
(array([ 9.97595914,  9.93244123, 10.00495032,  9.93742912,  9.94257389]),
 array([9.9808255 , 9.96965113, 9.90034447, 9.96543908, 9.95135268]))
In [396]:
# Plot qq plot for mean acceleration of standard and challenge tasks
fig, axs = plt.subplots(1, 2, figsize=(20, 4), sharex=True)
# Plot qq plot for the mean magnitude of acceleration for standard and challenge tasks
sm.qqplot(mean_acceleration_standard_magnitude, line='45', fit=True, ax=axs[0])
axs[0].set_xlabel('Theoretical Quantiles')
axs[0].set_ylabel('Sample Quantiles')
axs[0].set_title('QQ Plot of Mean Magnitude of Acceleration for Standard Task')
axs[0].legend()

sm.qqplot(mean_acceleration_challenge_magnitude, line='45', fit=True, ax=axs[1])
axs[1].set_xlabel('Theoretical Quantiles')
axs[1].set_ylabel('Sample Quantiles')
axs[1].set_title('QQ Plot of Mean Magnitude of Acceleration for Challenge Task')
axs[1].legend()
/var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/205138737.py:8: UserWarning: No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
  axs[0].legend()
/var/folders/zp/3681gr8x5mg9vt0z3xbtlzx00000gn/T/ipykernel_91614/205138737.py:14: UserWarning: No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
  axs[1].legend()
Out[396]:
<matplotlib.legend.Legend at 0x1368d4f40>
No description has been provided for this image
In [397]:
# Plot ecdf of sample means
import seaborn as sns

# Plot ecdf of sample means using subplots of grid 1,3 along x, y and z axis
fig, axs = plt.subplots(1, 3, figsize=(20, 6), sharex=True)
sns.ecdfplot(sample_means_standard_x, label='Standard', ax=axs[0])
sns.ecdfplot(sample_means_challenge_x, label='Challenge', ax=axs[0])
axs[0].set_xlabel('Mean Acceleration along x-axis (m/s²)')
axs[0].set_ylabel('ECDF')
axs[0].set_title('ECDF of Sample Means for Standard and Challenge Tasks')
axs[0].legend()

sns.ecdfplot(sample_means_standard_y, label='Standard', ax=axs[1])
sns.ecdfplot(sample_means_challenge_y, label='Challenge', ax=axs[1])
axs[1].set_xlabel('Mean Acceleration along y-axis (m/s²)')
axs[1].set_ylabel('ECDF')
axs[1].set_title('ECDF of Sample Means for Standard and Challenge Tasks')
axs[1].legend()

sns.ecdfplot(sample_means_standard_z, label='Standard', ax=axs[2])
sns.ecdfplot(sample_means_challenge_z, label='Challenge', ax=axs[2])
axs[2].set_xlabel('Mean Acceleration along z-axis (m/s²)')
axs[2].set_ylabel('ECDF')
axs[2].set_title('ECDF of Sample Means for Standard and Challenge Tasks')
axs[2].legend()
Out[397]:
<matplotlib.legend.Legend at 0x136b0ed10>
No description has been provided for this image
In [398]:
fig, axs = plt.subplots(1, 2, figsize=(20, 4), sharex=True)

sns.ecdfplot(mean_acceleration_standard_magnitude, label='Standard', ax=axs[0])
sns.ecdfplot(mean_acceleration_challenge_magnitude, label='Challenge', ax=axs[1])
axs[0].set_xlabel('Mean Acceleration (m/s²)')
axs[0].set_ylabel('ECDF')
axs[0].set_title('ECDF of Mean Magnitude of Acceleration for Standard Task')
axs[0].legend()

axs[1].set_xlabel('Mean Acceleration (m/s²)')
axs[1].set_ylabel('ECDF')
axs[1].set_title('ECDF of Mean Magnitude of Acceleration for Challenge Task')
axs[1].legend()
Out[398]:
<matplotlib.legend.Legend at 0x136b94370>
No description has been provided for this image
In [399]:
# Perform t-test for the magnitude of mean acceleration of standard and challenge tasks
mean_acc_standard = [df['acceleration_magnitude'].mean() for df in dfs_stand]
mean_acc_challenge = [df['acceleration_magnitude'].mean() for df in dfs_stand_challenge]

print(mean_acc_standard)
print(mean_acc_challenge)
[np.float64(9.97595913863206), np.float64(9.932441233984115), np.float64(10.0049503202501), np.float64(9.937429117145417), np.float64(9.942573890776329)]
[np.float64(9.980825501450173), np.float64(9.969651130304943), np.float64(9.900344471083827), np.float64(9.965439082840906), np.float64(9.95135267805302)]
In [400]:
# Plot the magnitude of acceleration for each participant as a scatter plot
import matplotlib.pyplot as plt

participants = range(1, len(mean_acc_challenge) + 1)

plt.scatter(participants, mean_acc_standard, label='Standard')
plt.scatter(participants, mean_acc_challenge, label='Challenge')
Out[400]:
<matplotlib.collections.PathCollection at 0x136c2ff70>
No description has been provided for this image
In [401]:
# Plot a bar chart of mean acceleration of standard and challenge tasks
participants = range(1, len(mean_acc_challenge) + 1)

plt.plot(participants, mean_acc_standard, marker='o', label='Standard')
plt.plot(participants, mean_acc_challenge, marker='o', label='Challenge')
plt.xlabel("Participant")
plt.ylabel("Mean Acceleration Magnitude")
plt.title("Sit-to-Stand: Standard vs Challenge")
plt.legend()
plt.grid(True)
plt.show()
No description has been provided for this image
In [402]:
# Paired t-test for the magnitude of mean acceleration of standard and challenge tasks
from scipy.stats import ttest_rel

t_stat, p_value = ttest_rel(mean_acc_standard, mean_acc_challenge)
print("Paired t-test result: \n")
print(f"t-statistic = {t_stat:.4f}")
print(f"p-value = {p_value:.4f}")
Paired t-test result: 

t-statistic = 0.2013
p-value = 0.8503
In [403]:
# Conclusion

print("Conclusion:")
print("*"*30)
if p_value < 0.05:
    print("There is a significant difference in the mean acceleration magnitude between the standard and challenge tasks.")
else:
    print("There is no significant difference in the mean acceleration magnitude between the standard and challenge tasks.")
Conclusion:
******************************
There is no significant difference in the mean acceleration magnitude between the standard and challenge tasks.
In [ ]:
 
In [ ]:
 
In [ ]: